﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Markup;
using Rhizome.Contract.Diag;
using Rhizome.Internal;
using Rhizome.Model.Validation;

namespace Rhizome.Model
{
	[ContentProperty("States")]
	public sealed class RandomTransition : TransitionBase, IValidate
	{
		private readonly Random _random = new Random();

		public RandomTransition()
		{
			States = new RhizomeElementCollection<RandomState>(this);
		}

		public Collection<RandomState> States { get; private set; }


		public override object GetTransitionState()
		{
			return GetRandomState();
		}

		private object GetRandomState()
		{
			switch (States.Count)
			{
					//case 0:
					//    throw new ValidationException("States must exists");

				case 1:
					return States[0].State;

				default:
					var sum = States.Sum(state => state.Value);
					var r = _random.NextDouble()*sum;
					var n = 0d;
					foreach (var s in States.OrderBy(s => _random.Next()))
					{
						n += s.Value;
						if (r <= n) return s.State;
					}

					throw new InvalidOperationException("Invalid algorithm");
			}
		}

		#region Overrides of RhizomeElement

		protected override IEnumerable<IEnumerable> GetElementCollections()
		{
			return base.GetElementCollections().Concat(new[] {States});
		}

		#endregion

		#region Implementation of IValidate

		IEnumerable<IValidationResult> IValidate.GetValidationResults()
		{
			if (States.Any() == false)
				yield return ValidationResult.StatesAreEmpty;
		}

		#endregion
	}
}